<?php
namespace App\Admin\Controllers\Auth;

use Closure;
use Illuminate\Support\Str;
use Illuminate\Support\Collection;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Admin\Admin;
use App\Admin\Controllers\Controller;

use PragmaRX\Google2FA\Google2FA;

class TwoFactorAuthenticationController extends Controller
{

	/**
	 * http://www.llc.com/api/admin/two-factor-authentication
	 */
	public function show(Request $request)
	{
		$user = Admin::user();
		$enabled = $user->hasEnabledTwoFactorAuthentication();
		$data = ['enabled'=>$enabled];

		if( $enabled === true ){
			$data['two_factor_confirmed_at'] = $user->two_factor_confirmed_at;
			$data['two_factor_recovery_codes'] = json_decode(decrypt($user->two_factor_recovery_codes));
		}


		if( $enabled === false ){
			$google2fa = new Google2FA();
			$secretKey = $google2fa->generateSecretKey(32);
			$user->two_factor_secret = $secretKey;
			$data['enabled_options'] = [
				'secret' => $user->two_factor_secret,
				'url' => $user->twoFactorQrCodeUrl(),
				'svg' => $user->twoFactorQrCodeSvg(),
			];
		}

		return Admin::success($data);
	}

	/**
	 * 启用双因素认证 enable
	 */
	public function store(Request $request, Google2FA $google2fa)
	{
		$validated = $request->validate([
			'secret' => 'bail|required|string|size:32',
			'code' => [
				'bail',
				'required',
				'integer',
				'digits:6',
		        function (string $attribute, mixed $value, Closure $fail) use($request, $google2fa) {
		            if( !$google2fa->verifyKey($request->input('secret'), $value) ) {
		                $fail("令牌未通过验证");
		            }
		        },
			],
		], [
			'code.required' => '请输入令牌',
			'code.integer'  => '令牌应该是6位数字',
			'code.digits'   => '令牌应该是6位数字',
			'code'          => '令牌未通过验证',
		]);


		$user = Admin::user();
        abort_if($user->hasEnabledTwoFactorAuthentication(), 403, '已经设置过双因素认证，请先关闭再设置');


		$recovery_codes = Collection::times(8, function () {
            return Str::random(10).'-'.Str::random(10);
        })->all();
		$user->forceFill([
			'two_factor_secret' => $validated['secret'],
			'two_factor_recovery_codes' => encrypt(json_encode($recovery_codes)),
			'two_factor_confirmed_at' => now(),
		])->save();

		return Admin::success();
	}

	/**
	 * 关闭双因素认证 disable
	 */
	public function destroy(Request $request)
	{
		$user = Admin::user();

        if (! is_null($user->two_factor_secret) ||
            ! is_null($user->two_factor_recovery_codes) ||
            ! is_null($user->two_factor_confirmed_at)) {

            $user->forceFill([
                'two_factor_secret' => null,
                'two_factor_recovery_codes' => null,
                'two_factor_confirmed_at' => null,
            ])->save();
        }

		return Admin::success();
	}

	/**
	 * 校验是否
	 */
	public function challenge(Request $request)
	{
		// code...
	}
}
